package com.atguigu.prototype.deepclone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Client {
    public static void main(String[] args) throws Exception{
        DeepProtoType p = new DeepProtoType();
        p.name = "宋江";
        p.deepCloneableTarget = new DeepCloneableTarget("大牛","小牛");

        //方式1完成深拷贝
//        DeepProtoType p2 = (DeepProtoType)p.clone();
//        System.out.println("p.name="+p.name+"p.deepCloneableTarget="+p.deepCloneableTarget.hashCode());
//        System.out.println("p2.name="+p2.name+"p2.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());

//        DeepProtoType p2 = (DeepProtoType)p.deepClone();
//        System.out.println("p.name="+p.name+"p.deepCloneableTarget="+p.deepCloneableTarget.hashCode());
//        System.out.println("p2.name="+p2.name+"p2.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());

        DeepProtoType p2 = (DeepProtoType)deepClone2(p);
        System.out.println("p.name="+p.name+"p.deepCloneableTarget="+p.deepCloneableTarget.hashCode());
        System.out.println("p2.name="+p2.name+"p2.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());
    }

    //问：如何修改成泛型
    //深拷贝-方式2 通过对象的序列化实现（推荐）
    public static Object deepClone2(DeepProtoType deepProtoType){
        DeepProtoType copyObj = null;

        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream outputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        try{
            //序列化
            byteArrayOutputStream = new ByteArrayOutputStream();
            outputStream = new ObjectOutputStream(byteArrayOutputStream);
            outputStream.writeObject(deepProtoType); //当前这个对象以对象流方式输出

            //反序列化
            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            copyObj = (DeepProtoType) objectInputStream.readObject();
            return copyObj;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }finally {
            try{
                byteArrayOutputStream.close();
                outputStream.close();
                byteArrayInputStream.close();
                objectInputStream.close();
            }catch (Exception e2){
                e2.printStackTrace();
            }
        }
    }
}
